#include "CharacterView.h"
#include <algorithm>

CharacterView::CharacterView( HexEditPanel* panel ): HexEditViewBase( panel ) {
}

void CharacterView::OnActivate( bool ) {
}

void CharacterView::OnOffsetChange(
  OffsetT,
  OffsetT,
  OffsetT,
  OffsetT ) {
}

void CharacterView::OnProcessChar( wxChar ch ) {
  if( !wxIsprint( ch ) || ch >= 0x100 ) {
    return;
  }
  if( GetCurrentOffset() >= GetContent()->GetSize() ) {
    return;
  }
  OffsetT nextPosition = std::min( GetContent()->GetSize(), GetCurrentOffset() + 1 );
  GetContent()->WriteByte(
    FileContentBase::ExtraUndoData( this, GetCurrentOffset(), 0, nextPosition, 0 ),
    GetCurrentOffset(),
    ( unsigned char ) ch );
  OnMoveRight();
}

void CharacterView::OnMoveLeft() {
  if( GetCurrentOffset() == 0 ) {
    return;
  }
  OffsetChange( GetCurrentOffset() - 1 );
}

void CharacterView::OnMoveRight() {
  if( GetCurrentOffset() >= GetContent()->GetSize() - 1 ) {
    return;
  }
  OffsetChange( GetCurrentOffset() + 1 );
}

void CharacterView::OnMoveUp() {
  if( GetCurrentOffset() < GetLineBytes() ) {
    return;
  }
  OffsetChange( GetCurrentOffset() - GetLineBytes() );
}

void CharacterView::OnMoveDown() {
  if( GetCurrentOffset() >= GetContent()->GetSize() - GetLineBytes() ) {
    return;
  }
  OffsetChange( GetCurrentOffset() + GetLineBytes() );
}

void CharacterView::OnPutLine( OffsetT startOffset, HexEditLineBuffer& buff, char* content, int bytes ) {
  for( int i = 0; i < bytes; ++i ) {
    buff.PutChar(
      Strip( *content++ ),
      ( startOffset + i != GetCurrentOffset() ) ? stNormal :
      GetActive() ? stCurCar : stCurNon
    );
  }
  int lineBytes = ( int )GetLineBytes();
  for( int i = bytes; i < lineBytes; ++i ) {
    buff.PutChar( ' ' );
  }
}

void CharacterView::OnGetBlockSizes( int& blockLength, int& blockBytes, int& spacing ) {
  blockLength = 1;
  blockBytes  = 1;
  spacing     = 0;
}

int CharacterView::OnGetOffsetFromColumn( int column, int& positionFlags ) {
  positionFlags = 0;
  return column;
}

inline char CharacterView::Strip( char ch ) {
  if( !isprint( ch ) ) {
    return ' ';
  }
  if( ch >= 0x7F ) {
    return ' ';
  }
  return ch;
}
